#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "list.h"

#include "num.h"
#include "time_count.h"

struct student
{
	int id;
	int age;
	struct list_head entry;
};

struct school
{
	LIST_HEAD_DEFINE(list_head_st);
	char name[20];
	char location[20];
};

struct person
{
    struct list_head en;
    char name[20];
    char gender[10];
};


struct student *st[STUDENT_NUM] = {NULL};

int main(int argc, char const *argv[])
{
	struct student * pos_st = NULL;
	struct student * pos_n = NULL;

    // struct list_head list_head_st = {&list_head_st, &list_head_st};
	struct school sc = {
		.location = "China",
		.name = "Peking",
		.list_head_st = LIST_HEAD_INIT(sc.list_head_st),
	};
	
	for (int i = 0; i < STUDENT_NUM; i++) {
		st[i] = (struct student *)malloc(sizeof(struct student));
		if (st[i] == NULL)
		{
			perror("malloc failed");
			return -1;
		}
		st[i]->id = i;
		st[i]->age = i + STUDENT_NUM;
	}

	struct timespec tp_s;
	tm_start(&tp_s);

	for (int i = 0; i < STUDENT_NUM; i++) {
		list_add_tail(&st[i]->entry, &sc.list_head_st);
	}

	list_for_each_entry(pos_st, &sc.list_head_st, entry)
	{
		// printf("id:[%d]  age[%d]\n", pos_st->id, pos_st->age);
	}
    printf("\n");

	// list_for_each_entry_safe(pos_st, pos_n, &sc.list_head_st, entry)
	// {
	// 	printf("id:[%d]  age[%d]\n", pos_st->id, pos_st->age);
	// }
    // printf("\n");

	tm_sub(&tp_s);

	for (int i = 0; i < STUDENT_NUM; i++)
    {
        free(st[i]);
    }

// =====================================
    // struct list_head list_head_st = {&list_head_st, &list_head_st};
	struct school sc2 = {
		.location = "China",
		.name = "Peking",
		.list_head_st = LIST_HEAD_INIT(sc2.list_head_st),
	};
	
	for (int i = 0; i < STUDENT_NUM; i++) {
		st[i] = (struct student *)malloc(sizeof(struct student));
		if (st[i] == NULL)
		{
			perror("malloc failed");
			return -1;
		}
		st[i]->id = i;
		st[i]->age = i + STUDENT_NUM;
	}

	tm_start(&tp_s);

	for (int i = 0; i < STUDENT_NUM; i++) {
		list_add_tail(&st[i]->entry, &sc2.list_head_st);
	}

	list_for_each_entry(pos_st, &sc2.list_head_st, entry)
	{
		// printf("id:[%d]  age[%d]\n", pos_st->id, pos_st->age);
	}
    printf("\n");

	// list_for_each_entry_safe(pos_st, pos_n, &sc.list_head_st, entry)
	// {
	// 	printf("id:[%d]  age[%d]\n", pos_st->id, pos_st->age);
	// }
    // printf("\n");
	tm_sub(&tp_s);

	for (int i = 0; i < STUDENT_NUM; i++)
    {
        free(st[i]);
    }
#if 0
	struct person * pos_ps = NULL;
	struct person * pos_nps = NULL;

	struct person PA = {{NULL, NULL}, "PA", "男"};
	struct person PB = {{NULL, NULL}, "PB", "女"};
	struct person PC = {{NULL, NULL}, "PC", "男"};
	struct person PD = {{NULL, NULL}, "PD", "女"};

    // struct list_head list_head_ps = {&list_head_ps, &list_head_ps};
	LIST_HEAD(list_head_ps);

	list_add_tail(&PA.en, &list_head_ps);
	list_add_tail(&PB.en, &list_head_ps);
	list_add_tail(&PC.en, &list_head_ps);
	list_add_head(&PD.en, &list_head_ps);

	list_for_each_entry_safe(pos_ps, pos_nps, &list_head_ps, en)
	{
		printf("name:[%s]  gender[%s]\n", pos_ps->name, pos_ps->gender);
        if (strcmp(pos_ps->name, "PB") == 0)
            list_del(&pos_ps->en);
	}
    printf("\n");

    // 删除节点时，迭代器失效，会出现Segmentation fault
	list_for_each_entry(pos_ps, &list_head_ps, en)
	{
		printf("name:[%s]  gender[%s]\n", pos_ps->name, pos_ps->gender);
        if (strcmp(pos_ps->name, "PA") == 0)
            list_del(&pos_ps->en);
	}
    printf("\n");

#endif

	return 0;
}
